package com.xingchi.tornado.storage.core.supports;

import com.xingchi.tornado.storage.core.AbstractFileStorageService;
import com.xingchi.tornado.storage.core.config.StorageProperties;
import com.xingchi.tornado.storage.core.exception.FileUploadException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.FileCopyUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;

/**
 * 本地存储服务
 *
 * @author xingchi
 * @date 2024/4/21 20:50
 */
@Slf4j
public class LocalFileStorageService extends AbstractFileStorageService {

    private final String filePath;
    private final StorageProperties.LocalProperties localProperties;

    public LocalFileStorageService(StorageProperties.LocalProperties localProperties) {

        if (StringUtils.isBlank(localProperties.getFilePath())) {
            throw new FileUploadException("文件上传失败，请配置文件上传路径");
        }

        this.filePath = localProperties.getFilePath();
        this.localProperties = localProperties;
        log.info("local file storage service init successfully!");
    }

    /**
     * 根据文件的输入流上传文件
     *
     * @param is       文件的输入流
     * @param fileName 文件的完整名称
     * @return 文件在文件存储服务器上的路径唯一标识，在云存储中返回文件的对象名
     */
    @Override
    public String uploadFile(InputStream is, String fileName) {
        String path = getPath(fileName);
        String savePath = getPath(filePath, path);

        try {
            File file = new File(savePath);
            File parentFile = file.getParentFile();
            if (!parentFile.exists() && !parentFile.mkdirs()) {
                log.warn("文件上传失败，无法创建对应的文件路径");
                throw new FileUploadException("文件上传失败");
            }
            FileCopyUtils.copy(is, Files.newOutputStream(file.toPath()));
        } catch (IOException e) {
            log.warn("文件上传失败，原因：{}", e.getMessage(), e);
            throw new FileUploadException("文件上传失败");
        }

        return path;
    }

    /**
     * 根据文件在文件服务器上的存储路径获取文件对应的字节书，注意文件过大可能会导致内存溢出问题
     *
     * @param path 文件的存储路径
     * @return 文件字节
     */
    @Override
    public byte[] getFileBytes(String path) {
        File oigFile = new File(filePath + path);

        try {
            return FileCopyUtils.copyToByteArray(oigFile);
        } catch (IOException e) {
            log.warn("文件转换失败，原因：{}", e.getMessage(), e);
            return EMPTY_BYTES;
        }
    }

    /**
     * 删除文件
     *
     * @param path 文件的存储路径
     */
    @Override
    public void deleteFile(String path) {
        try {
            FileUtils.deleteQuietly(new File(filePath + path));
        } catch (Exception e) {
            log.warn("删除文件异常", e);
        }
    }

}
